package com.gyz.cfmall.search.thread;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author: gongyuzhuo
 * @since: 2023/3/26 19:39
 * @description:
 */
public class CompletableFutureDemo {
    public static ExecutorService service = Executors.newFixedThreadPool(10);

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // >>>>>>>>>>whenComplete>>>>>>
//        System.out.println("main...start...");
//        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
//            System.out.println("当前线程：" + Thread.currentThread().getId());
//            int i = 10 / 5;
//            System.out.println("计算结果：" + i);
//            return i;
//        }, service).whenComplete((res, exception) -> {
//            System.out.println("异步任务执行完成了...结果是：" + res + "异常是：" + exception);
//        });
//        System.out.println("main...end...");

        // >>>>>>>>>>exceptionally>>>>>>
//        System.out.println("main...start...");
//        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
//            System.out.println("当前线程：" + Thread.currentThread().getId());
//            int i = 10 / 0;
//            System.out.println("计算结果：" + i);
//            return i;
//        }, service).whenComplete((res, exception) -> {
//            System.out.println("异步任务执行完成了...结果是：" + res + "异常是：" + exception);
//        }).exceptionally(throwable -> {
//            return 10;
//        });
//        System.out.println("main...end..." + future.get());

        // >>>>>>>>>>handle >>>>>>
//        System.out.println("main...start...");
//        CompletableFuture<Integer> handle = CompletableFuture.supplyAsync(() -> {
//            System.out.println("当前线程为：" + Thread.currentThread().getId());
//            int i = 10 / 4;
//            System.out.println("结算结果：" + i);
//            return i;
//        }, service).handle((res, exception) -> {
//            if (res != null) {
//                return res * 2;
//            }
//            if (exception != null) {
//                return 0;
//            }
//            return 0;
//        });
//        System.out.println("main...end..." + handle.get());

        // >>>>>>>>>>thenRunAsync: 不能获取上一个任务的返回结果>>>>>>
//        System.out.println("main...start...");
//        CompletableFuture<Void> thenRunAsync = CompletableFuture.supplyAsync(() -> {
//            System.out.println("当前线程为：" + Thread.currentThread().getId());
//            int i = 10 / 4;
//            System.out.println("结算结果：" + i);
//            return i;
//        }, service).thenRunAsync(() -> {
//            System.out.println("任务2开始运行");
//        }, service);
//        System.out.println("main...end...");

//        // >>>>>>>>>>thenAcceptAsync：可以获取上个任务的返回结果，但是不能返回结果>>>>>>
//        System.out.println("main...start...");
//        CompletableFuture<Void> thenRunAsync = CompletableFuture.supplyAsync(() -> {
//            System.out.println("当前线程为：" + Thread.currentThread().getId());
//            int i = 10 / 4;
//            System.out.println("结算结果：" + i);
//            return i;
//        }, service).thenAcceptAsync((res) -> {
//            System.out.println("任务2开始运行：" + res);
//        }, service);
//        System.out.println("main...end...");

//        // >>>>>>>>>>thenApplyAsync：可以获取上个任务的返回结果，但是不能返回结果>>>>>>
//        System.out.println("main...start...");
//        CompletableFuture<String> thenApplyAsync = CompletableFuture.supplyAsync(() -> {
//            System.out.println("当前线程为：" + Thread.currentThread().getId());
//            int i = 10 / 4;
//            System.out.println("结算结果：" + i);
//            return i;
//        }, service).thenApplyAsync((res) -> {
//            System.out.println("任务2开始运行...");
//            return "hello" + res;
//        }, service);
//        System.out.println("main...end..." + thenApplyAsync.get());

        System.out.println("main...start...");
        CompletableFuture<Integer> future01 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务A开始执行" + Thread.currentThread().getId());
            int i = 10 / 4;
            System.out.println("任务A执行完成，计算结果：" + i);
            return i;
        }, service);


        CompletableFuture<String> future02 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务B开始执行" + Thread.currentThread().getId());
            System.out.println("任务B执行完成");
            return "hello!";
        }, service);

        CompletableFuture<Object> future = future01.thenCombineAsync(future02, (r1, r2) -> {
            System.out.println("任务C开始执行" + Thread.currentThread().getId());
            System.out.println("任务C执行完成");
            return "A任务执行结果，Result：" + r1 + ",B任务执行结果：" + r2;
        }, service);

        System.out.println("main...end..."+future.get());
    }
}
